package com.tim;

import cn.hutool.crypto.digest.MD5;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.tim.helper.string.StrTransformer;
import com.tim.third.YmlUtils;
import com.tim.util.CmdAndShUtil;
import com.tim.util.FileUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.utils.LogUtil;
import org.junit.Test;
import org.slf4j.MDC;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class StringHelper {
	StrTransformer h1;// url、base64、unicode转换

	@Test
	public void fast() throws Exception {
		String path = StringHelper.class.getProtectionDomain().getCodeSource().getLocation().getPath();
		path = java.net.URLDecoder.decode(path, "UTF-8");

		System.out.println("方式1"+path);
		String path1 = System.getProperty("java.class.path");
		int firstIndex = path1.lastIndexOf(System.getProperty("path.separator")) + 1;
		int lastIndex = path1.lastIndexOf(File.separator) + 1;
		path1 = path1.substring(firstIndex, lastIndex);
		System.out.println("方式2"+path1);

	}

	/**
	 * 对比字符串，不同的字符，输出为error*/
	@Test
	public void compareChars(){
		String str1 = "needCharge__Gwayl___20001____CHARGE_CHARGE____MERCHANT123";
		String str2 = "needCharge__Gwayl___0001____CHARGE_CHARGE____MERCHANT";

		System.out.println(str1);
		StringBuffer buffer = new StringBuffer();
		int i = 0;
		for (; i < str1.length(); i++) {
			if(i>=str2.length()){
				break;
			}

			boolean flag = str1.charAt(i)==str2.charAt(i);
			if (flag){
				buffer.append(str2.charAt(i));
			}else{
				System.out.println(StringUtils.repeat(" ", i-buffer.length())+buffer);
				System.out.flush();
				buffer = new StringBuffer();
				System.err.println(StringUtils.repeat(" ", i)+str2.charAt(i));
				System.err.flush();
			}
		}
		if(buffer.length()!=0){
			System.out.println(StringUtils.repeat(" ", i-buffer.length())+buffer);
		}

		if(str2.length()>str1.length()){
			System.err.println(StringUtils.repeat(" ", str1.length())+str2.substring(str1.length()));
		}


	}



	@Test
	public void strToJson(){
		String str = "";

		str = str.substring(str.indexOf('{'), str.lastIndexOf('}')+1);
		str = str.replaceAll("\\s", "");
		str = str.replaceAll("\\(", "{");
		str = str.replaceAll("\\)", "}");
		str = str.replaceAll("=[\\w\\.]+\\{", "={");
		str = str.replaceAll("=", ":");
		str = str.replaceAll("(:|,)", "\"$1\"");
		str = str.replaceAll("\\{", "{\"");
		str = str.replaceAll("\\}", "\"}");
		str = str.replaceAll("\"\\{", "{");
		str = str.replaceAll("\\}\"", "}");
		str = str.replaceAll("\\{\"\"\\}", "{}");
		str = str.replaceAll("\"null\"", "null");

		System.out.println(JSONUtil.formatJsonStr(str));
	}

	@Test
	public void searchTmcs() throws IOException {
		String path = new ClassPathResource("application2.yml").getFile().getAbsolutePath();
		Map<String, Object> map = YmlUtils.loadYml(path);
		String splitor = "(白茶小助手)|(小莉往前冲)|(买菜菜啊)";
		String searchWord = map.get("searchWord").toString();
		String excludeWord = map.get("excludeWord").toString();
		String searchFilePath = map.get("searchFilePath").toString();

		String wordSplitor = "[,，]+";
		String[] strs =
            Files.readAllLines(Paths.get(searchFilePath)).stream()
                .collect(Collectors.joining("\n"))
                .split(splitor);

    	int num = 0;
    	StringBuilder builder = new StringBuilder();
		String[] sWords = searchWord.split(wordSplitor);
		String[] exWords = excludeWord.split(wordSplitor);
		for(String str : strs){
			if(StringUtils.containsAny(str, sWords)
					&& !StringUtils.containsAny(str, exWords)){
				num++;
				builder.append(str).append("\n");
			}
		}
		System.out.println("条目数："+num);
		System.out.println(builder);
	}

	@Test
	public void unicodeToChinese(){
		// Unicode编码字符串
		String unicode = "\\u4e2d\\u6587中文";

		// 使用正则表达式替换Unicode编码
		Pattern pattern = Pattern.compile("\\\\u([0-9a-fA-F]{4})");
		Matcher matcher = pattern.matcher(unicode);
		StringBuffer buffer = new StringBuffer();

		while (matcher.find()) {
			String hex = matcher.group(1);
			int codePoint = Integer.parseInt(hex, 16);
			matcher.appendReplacement(buffer, Character.toString((char) codePoint));
		}
		matcher.appendTail(buffer);

		System.out.println(buffer.toString());  // 输出: 中文

	}

	@Test
	public void  chineseToUnicode (){
		String chinese = "中文";  // 汉字字符串

		// 将汉字转换为Unicode编码
		StringBuilder sb = new StringBuilder();
		for (char c : chinese.toCharArray()) {
			sb.append("\\u").append(Integer.toHexString(c | 0x10000).substring(1));
		}

		System.out.println(sb.toString());  // 输出: \u4e2d\u6587
	}


	// 备份有道笔记
    @Test
    public void youdaoBak() throws Exception {
        String cookieStr = "OUTFOX_SEARCH_USER_ID=-154972435@14.106.78.42; _ntes_nnid=2d7816bc4efd2eac57532317a1ba8730,1620097185789; _ga=GA1.2.1133477752.1648472905; _9755xjdesxxd_=32; YD00688109880970:WM_TID=gVArI8WizqdAUBEEQBJr7+cQzHEoqmUy; YNOTE_USER=1; YD00688109880970:WM_NI=NnOw/M/KOKqc3Cp8iiD6Wn9E937XnJjYfTBahrO2qjl44A+HPzZwB7E5YOPHVavaW4DKf+LDr73te6WLE3dI27nbCKca5n9nzT0qDiiOGzgYodw0rn+0cQf5z1ff1t8fazQ=; YD00688109880970:WM_NIKE=9ca17ae2e6ffcda170e2e6eed0bc48b69884d5b17a91ef8ab7d55f939b9eb1c444b095fe8eeb4d93b2bfb6ea2af0fea7c3b92a8eb28198ae47ed9581acf469f19dc0d9ec6388ea998fbc4ffbedf9b9ed42aa87aab5c16bacae81d3f462b0ecfca2aa4494a69698c13d87eb97b0d34496bfba82d6408895aacccf50b2e9fd95e83e95948bd4e743f2e9a283c241a1bffb8fbc66ba8c0092c763ab91899be653adbcb9d1f166e9f0adb2e53fbaefaa87b480fcbaaf9bd437e2a3; OUTFOX_SEARCH_USER_ID_NCOO=1461005887.7349422; YD00053006227227:WM_NI=bEK9xNgfCfC09bIWvfQexzgPQ/S0H8gfUexN5Kgf8wFEF4VUhvGSs5b7Vs8LNTY1+SVkZH5yFLuFOrG05ZRDROamXrvdRdmLIlUga16SgTw9ABi8hK2L2evkYwKbBsUdZzY=; YD00053006227227:WM_NIKE=9ca17ae2e6ffcda170e2e6eedaf96298befa8df143a29a8eb2c44b969e8e83c4639890afd3cd34a5ef81d7b42af0fea7c3b92aa29b85dafb46a5ba8d87c23cfbbe87b8f56e93bbb89be65c93f19dd1cb34a5ba9b86fb46f795a987bb7d869b8ad5d55facaa89b4f23fa2e99a94bb488e8c97d2aa5996b596a9b8738694bba7ce7a85f0fbbbd1509291af8edb7ab6bc9e85f0488bb49b88e43bf68da9b5f633839ea7d9eb41f294fe86f5619ba98583c17997bc969bdc37e2a3; YD00053006227227:WM_TID=KLXKTKU+TEdAAURBFEfAmSaajcsl0a/x; __yadk_uid=c8zROvXXVRovW2Xgy4174hLsR4Thp6BE; Hm_lvt_daa6306fe91b10d0ed6b39c4b0a407cd=1696995246,1698113877; P_INFO=18183182516|1698114823|1|youdaonote|00&99|null&null&null#chq&null#10#0|&0||18183182516; YNOTE_PERS=v2|cellphone||YNOTE||web||-1||1698114823983||183.230.37.149||yun6713@126.com||6uk4Ylh4pS0QL0LqSO4Of0TL0HQB0fTy0TFRLQ4hHzG0kWPMpK64euRquRMYGhMguRp4O4gKhfqu0pLhMeLk4Q40; DICT_UGC=be3af0da19b5c5e6aa4e17bd8d90b28a|; JSESSIONID=abc39HAvk6DOE7GF2w_Ty; YNOTE_SESS=v2|EmLVwu_VYVOGhMgLOMOfRU5RLwuRMQBRqLkMOM0fP40JK6MQZ6LYl0UW0fJyRHJS0eunfpykMpK0PzOLpLhfqK0p4PLzfP4lm0; YNOTE_LOGIN=5||1698808021583; YNOTE_CSTK=OktQqMIf; Hm_lvt_30b679eb2c90c60ff8679ce4ca562fcc=1698808026; Hm_lpvt_30b679eb2c90c60ff8679ce4ca562fcc=1698808026" +
                "" +
                "";
        String dir = "C:\\project\\github\\youdaonote-pull/";
        Path configPath = Paths.get(dir, "cookies.json");
        Map<String, String> map = Arrays.stream(cookieStr.split(";"))
                .map(String::trim)
                .map(e -> e.split("="))
                .filter(e -> e.length == 2)
                .collect(Collectors.toMap(strs -> strs[0], strs -> strs[1]));
        String content = Files.readAllLines(configPath).stream().collect(Collectors.joining());
        JSONObject jsonObject = JSON.parseObject(content);
        JSONArray cookies = jsonObject.getJSONArray("cookies");
        for (int i = 0; i < cookies.size(); i++) {
            JSONArray jsonArray = cookies.getJSONArray(i);
            jsonArray.set(1, map.get(jsonArray.getString(0)));
        }
        Files.write(configPath, Collections.singleton(JSON.toJSONString(jsonObject, true)));
        MDC.clear();
        CmdAndShUtil.runBatInWindow(dir+"start.bat");
    }

	@Test// 转换md5密码
	public void printMd5Password(){
		String pwd = "123456";
		String md5Pwd = MD5.create().digestHex(pwd,
				"UTF-8");//.toUpperCase();
		System.out.println(md5Pwd.toUpperCase());
	}

	@Test
	public void cmdCurl(){
		String curl = "";
		curl = curl.replaceAll("\\\\", "^")
				.replaceAll("\"", "\\\\\"")
				.replaceAll("'", "\"")
				.replaceAll("", "");
		System.out.println(curl);
	}

	@Test
	public void sysEnv(){
		Map<String, String> osEnv = System.getenv();
		Properties jvmProps = System.getProperties();
		System.out.println(osEnv);
		System.out.println(jvmProps);
	}

	@Test// 解析jwt token信息
	public void decodeJwtToken(){
		String token = "";
		String[] parts = token.split("\\.");;
		try {
			String payloadJson = org.apache.commons.codec.binary.StringUtils.newStringUtf8(Base64.decodeBase64(parts[1]));
			System.out.println(payloadJson);
      		System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(JWT.decode(token).getExpiresAt()));
      	} catch (NullPointerException e) {
			throw new JWTDecodeException("The UTF-8 Charset isn't initialized.", e);
		}

	}

	/**打印日志*/
	@Test
	public void printLogInfo(){
    String info =
        "";

		if(info.trim().startsWith("{")){
			JSONObject jsonObject = JSONObject.parseObject(info);
			if(jsonObject.containsKey("errStack")){
				info = jsonObject.getString("errStack");
			}else if(jsonObject.containsKey("message")){
				info = JSONObject.parseObject(info).getString("message");
			}
		}
		info = info.replaceAll("\"errDesc\":","\n\"errDesc\":")
				.replaceAll("\"errStack\":","\n\"errStack\":")
				.replaceAll("\\\\t", "\t")
				.replaceAll("\\\\n", "\n")
				.replaceAll("([\\.\\w+]+Exception)", "\n$1")
				.replaceAll(" at ","\n\t at ")
				.replaceAll("\\)at ",")\n\t at ")
				.replaceAll(" at\\s+\n"," at ");

		System.out.println(info);
	}

	@Test// 重复信息
	public void printDuplicateInfo() {
    String str =
        "";
    		String template = "delete from lessee_order_%02d;";

		String[] split = str.replaceAll("\\s+", "").split(",");
//		for(String s : split){
//			System.out.println(String.format(template, StringAnalysisUtil.head2UpperCase(s)));
//		}

		for (int i = 0; i < 100; i++) {
			System.out.println(String.format(template, i));
		}
	}

	@Test// 去换行、转换编码、json格式化
	public void formatJson(){
    String info =
        "";
    info = new String(info.getBytes(Charset.forName("GBK")), StandardCharsets.UTF_8);
		info = info.replaceAll("[\r\n]", "");

		System.out.println(JSONUtil.formatJsonStr(info));
	}

	@Test
	public void iosParam2Json(){
		String str = "{\n" +
				"  id = \"2134286903082938\";\n" +
				"  addressModel = {\n" +
				"    showDistance = 0;\n" +
				"    lng = \"106.577911\";\n" +
				"    bugingMode = 0;\n" +
				"    lat = \"29.559059\";\n" +
				"    name = \"金手指女子SPA馆·Yoni体验店\";\n" +
				"    detailAddr = \"解放碑街道民族路188号38层2号\";\n" +
				"    isSelected = 0;\n" +
				"  };\n" +
				"  save = 0;\n" +
				"  consigneeAddrId = \"2134286903082938\";\n" +
				"  isDefault = 0;\n" +
				"  addressGrade = 0;\n" +
				"  lng = \"106.577911\";\n" +
				"  address = \"解放碑街道民族路188号38层2号 金手指女子SPA馆·Yoni体验店 11号\";\n" +
				"  addressDetail = \"重庆市,重庆市,渝中区\";\n" +
				"  addrDetail = \"重庆市,重庆市,渝中区\";\n" +
				"  lat = \"29.559059\";\n" +
				"  consigneeMobile = \"18581024363\";\n" +
				"  completeAddress = \"解放碑街道民族路188号38层2号 金手指女子SPA馆·Yoni体验店 11号(解放碑街道民族路188号38层2号)\";\n" +
				"  hourseAddress = \"11号\";\n" +
				"  mapAddress = \"金手指女子SPA馆·Yoni体验店\";\n" +
				"  accountId = \"2133701341167967\";\n" +
				"  amapStreet = \"解放碑街道民族路188号38层2号\";\n" +
				"  tel = \"18581024363\";\n" +
				"  consigneeName = \"黄智超11\";\n" +
				"}";
		str = str.replaceAll("\\s", "")
//				.replaceAll("\"", "")
				.replaceAll(";\n", ",\"\n")
				.replaceAll("=", "\":")
				.replaceAll("\\{", "{\"")
				.replaceAll("}", "\"}")
				.replaceAll(",\"\"}", "}");
		System.out.println(str);
	}


	/**json转md，xmind导入*/
	public static final String PADDING = "#";
	public static final String FIRST_MENU = "##";
	@Test
	public void json2XmindTree(){
		String jsonStr = "";
		String resultAttrName = "result";// 结果字段，多层.隔开
		String childrenAttrName = "children";
		String menuAttrName = "menuName";

		List<String> content = new ArrayList<>();// 结果
		JSONObject json = JSON.parseObject(jsonStr);
		resultAttrName = resultAttrName.trim();
		int dotIndex = resultAttrName.indexOf('.');
		if(dotIndex>-1){
			// 多层
			String[] strs = resultAttrName.split("\\.");
			resultAttrName = strs[strs.length-1];
			for (int i = 0; i < strs.length-1; i++) {
				json = json.getJSONObject(strs[i]);
			}
		}
		JSONArray menuList = json.getJSONArray(resultAttrName);
		handle(childrenAttrName, menuAttrName, FIRST_MENU, content, menuList);
		System.out.println("# 菜单树\n");
		content.forEach(e->System.out.println(e+"\n"));

	}

	private void handle(String childrenAttrName, String menuAttrName, String padding, List<String> content, JSONArray menuList) {
		for (int i = 0; i < menuList.size(); i++) {
			JSONObject menu = menuList.getJSONObject(i);
			String menuName = menu.getString(menuAttrName);
			content.add((FIRST_MENU.equals(padding)?padding+" "+i+"，":padding+" ")+menuName);
			JSONArray children = menu.getJSONArray(childrenAttrName);
			if(!CollectionUtils.isEmpty(children)){
				handle(childrenAttrName, menuAttrName, padding+PADDING, content, children);
			}

		}
	}


	String markStr = "LLLLLLLLLLLLLLLLLLL";
	String targetFile = MainHelper.OUTPUT_DIR+"/merge";
	@Test
	// 合并文件，递归。对jar、class无效
	public void mergeFiles() throws IOException {
		String dir = "C:\\project\\github\\autil\\autil\\src" +
				"" +
				"" +
				"";
		boolean notFilter = true;

		final Path targetFilePath = Paths.get(targetFile);
		Files.deleteIfExists(targetFilePath);
		// 指定文件编码为UTF-8
		Files.write(targetFilePath,
				new byte[]{(byte) 0xEF,(byte) 0xBB,(byte) 0xBF},
				StandardOpenOption.CREATE_NEW,
				StandardOpenOption.APPEND
		);
		Files.walkFileTree(Paths.get(dir), new SimpleFileVisitor<Path>(){
			public FileVisitResult visitFile(Path path, BasicFileAttributes attrs)
					throws IOException
			{
				if(notFilter || path.toString().endsWith(".java")){

					Files.write(targetFilePath,
							(markStr+"\n").getBytes(),
							StandardOpenOption.APPEND
					);

					String relativePath = path.toString()
							.substring(dir.length())
							.replaceFirst("[\\\\/]+", "")
							+"\n";
					Files.write(targetFilePath,
							relativePath.getBytes(),
							StandardOpenOption.APPEND
					);
					Files.write(targetFilePath,
							Files.readAllBytes(path),
							StandardOpenOption.APPEND
					);
				}
				return FileVisitResult.CONTINUE;
			}
		});


	}

	@Test
	// 拆分文件
	// jar包压缩、解压：
	// 	jar -xvf xxx.jar
	// 	jar -cvfM0 xxx.jar BOOT-INF/ META-INF/ org/
	public void splitFiles() throws IOException {
		String dir = MainHelper.OUTPUT_DIR;

		String content = new String(Files.readAllBytes(Paths.get(targetFile)));
		String[] split = content.split(markStr+"[^\"]");
		for(String str : split){
			if(StringUtils.isBlank(str)){
				continue;
			}
			String[] lines = str.trim().split("[\r\n]+");
			String line = lines[0].trim();
			Path targetPath = Paths.get(dir, line);
			File parentDir = targetPath.getParent().toFile();
			if(!parentDir.exists()){
				parentDir.mkdirs();
			}
			Files.write(targetPath,
					Arrays.stream(lines).skip(1).collect(Collectors.joining("\n")).getBytes(),
					StandardOpenOption.CREATE,
					StandardOpenOption.APPEND
			);
		}

	}

}
